package com.kerbores.kop.client;

import java.util.HashMap;
import java.util.Map;

import org.nutz.http.Header;
import org.nutz.http.Request;
import org.nutz.http.Request.METHOD;
import org.nutz.http.Response;
import org.nutz.http.sender.PostSender;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;

import com.kerbores.kop.common.SignUtil;
import com.kerbores.kop.common.exception.KOPException;
import com.kerbores.utils.entries.Result;
import com.kerbores.utils.net.IxionFileUploadPoster;

/**
 * KOP调用客户端
 * 
 * @author Kerbores
 *
 */
public class KOPClient {

	/**
	 * 
	 * @param serviceUrl
	 *            服务地址
	 * @param method
	 *            调用方法
	 * @param params
	 *            参数
	 * @param appKey
	 *            appKey
	 * @param appSecret
	 *            appSecret
	 * @return KOP客户端
	 */
	public static KOPClient creat(String serviceUrl, String method, Map<String, Object> params, String appKey, String appSecret) {
		return creat(serviceUrl, method, params, appKey, appSecret, false);
	}

	/**
	 * 创建客户端
	 * 
	 * @param serviceUrl
	 *            服务地址
	 * @param method
	 *            方法
	 * @param params
	 *            参数
	 * @param appKey
	 *            appKey
	 * @param appSecret
	 *            appSecret
	 * @param fileUpload
	 *            是否上传文件标识
	 * @return KOP客户端
	 */
	public static KOPClient creat(String serviceUrl, String method, Map<String, Object> params, String appKey, String appSecret, boolean fileUpload) {
		KOPClient client = new KOPClient();
		params.put("method", method);
		Request request = Request.create(serviceUrl, METHOD.POST, params);
		Map<String, String> properties = new HashMap<String, String>();
		properties.put("method", method);
		properties.put("appKey", appKey);
		properties.put("appSecret", appSecret);
		properties.put("fileUpload", fileUpload ? "1" : "0");
		properties.put("sign", SignUtil.getSign(params, fileUpload, appKey, appSecret));
		Header header = Header.create(properties);
		request.setHeader(header);
		PostSender poster = fileUpload ? new IxionFileUploadPoster(request) : new PostSender(request);
		client.poster = poster;
		return client;
	}

	private String serviceUrl;
	private String appKey;
	private String appSecret;

	/**
	 * 请求发送器
	 */
	private PostSender poster;

	KOPClient() {

	}

	/**
	 * 
	 * @param serviceUrl
	 *            服务地址
	 * @param method
	 *            调用方法
	 * @param params
	 *            参数
	 * @param appKey
	 *            appKey
	 * @param appSecret
	 *            appSecret
	 */
	public KOPClient(String serviceUrl, String method, Map<String, Object> params, String appKey, String appSecret) {
		this.poster = creat(serviceUrl, method, params, appKey, appSecret).poster;
	}

	/**
	 * 
	 * @param serviceUrl
	 *            服务地址
	 * @param method
	 *            调用方法
	 * @param params
	 *            参数
	 * @param appKey
	 *            appKey
	 * @param appSecret
	 *            appSecret
	 * @param fileUpload
	 *            文件上传标识
	 */
	public KOPClient(String serviceUrl, String method, Map<String, Object> params, String appKey, String appSecret, boolean fileUpload) {
		this.poster = creat(serviceUrl, method, params, appKey, appSecret, fileUpload).poster;
	}

	/**
	 * 通用构造
	 * 
	 * @param serviceUrl
	 *            服务地址
	 * @param appKey
	 *            appKey
	 * @param appSecret
	 *            appSecret
	 */
	public KOPClient(String serviceUrl, String appKey, String appSecret) {
		this.appKey = appKey;
		this.appSecret = appSecret;
		this.serviceUrl = serviceUrl;
	}

	/**
	 * 执行
	 * 
	 * @return 响应Result对象
	 */
	@Deprecated
	public Result send() {
		Response response = poster.send();
		int status = response.getStatus();
		if (status != 200) {
			throw new KOPException("response with code: " + status);
		}
		return Lang.map2Object(Lang.map(response.getContent()), Result.class);
	}

	/**
	 * 
	 * @param method
	 *            方法
	 * @param params
	 *            参数
	 * @return 调用结果Result描述
	 */
	public Result send(String method, Map<String, Object> params) {
		return send(method, params, false);
	}

	/**
	 * 
	 * @param method
	 *            方法
	 * @param params
	 *            参数
	 * @param fileUpload
	 *            是否文件上传
	 * @return 调用结果Result描述
	 */
	public Result send(String method, Map<String, Object> params, boolean fileUpload) {
		if (Strings.isBlank(serviceUrl) || Strings.isBlank(appKey) || Strings.isBlank(appSecret)) {
			throw new KOPException("Init client with serviceUrl appKey and appSecret");
		}
		return creat(serviceUrl, method, params, appKey, appSecret, fileUpload).send();
	}

}
